package com.joysuch.wwyt.openapi.services.serviceV1.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.Lists;
import com.joysuch.wwyt.api.basedata.service.BpJobSyncService;
import com.joysuch.wwyt.bp.entity.BpJob;
import com.joysuch.wwyt.bp.entity.dsl.QBpJob;
import com.joysuch.wwyt.bp.enums.DataStateTypes;
import com.joysuch.wwyt.bp.repository.BpJobDao;
import com.joysuch.wwyt.core.common.util.DateTimeUtil;
import com.joysuch.wwyt.core.entity.BaseUser;
import com.joysuch.wwyt.core.enums.Status;
import com.joysuch.wwyt.core.repository.BaseUserDao;
import com.joysuch.wwyt.core.support.Context;
import com.joysuch.wwyt.dzhapi.bean.ApiBaseUserBean;
import com.joysuch.wwyt.dzhapi.bean.ApiBpDepartBean;
import com.joysuch.wwyt.dzhapi.bean.ApiBpJobBean;
import com.joysuch.wwyt.dzhapi.bean.ApiRiskDistrictBean;
import com.joysuch.wwyt.dzhapi.dto.BuildDataDto;
import com.joysuch.wwyt.dzhapi.mapper.ApiBaseUserMapper;
import com.joysuch.wwyt.dzhapi.mapper.ApiBpJobMapper;
import com.joysuch.wwyt.dzhapi.mapper.ApiRiskDistrictMapper;
import com.joysuch.wwyt.mh.DateUtils;
import com.joysuch.wwyt.openapi.constants.ApiCode;
import com.joysuch.wwyt.openapi.constants.ApiStatus;
import com.joysuch.wwyt.openapi.controllers.controllerV1.req.ApiV1BpJobQueryReq;
import com.joysuch.wwyt.openapi.controllers.controllerV1.req.ApiV1BpJobReq;
import com.joysuch.wwyt.openapi.controllers.controllerV1.req.ApiV1BpJobUpdateReq;
import com.joysuch.wwyt.openapi.controllers.controllerV1.req.ApiV1QueryListReq;
import com.joysuch.wwyt.openapi.controllers.controllerV1.vo.*;
import com.joysuch.wwyt.openapi.controllers.controllerV1.vo.ApiResultData;
import com.joysuch.wwyt.openapi.exception.ApiV1ExceptionCodeMsg;
import com.joysuch.wwyt.openapi.services.serviceV1.ApiV1BpJobService;
import com.joysuch.wwyt.risk.entity.RiskDistrict;
import com.joysuch.wwyt.risk.repository.RiskDistrictDao;
import com.joysuch.wwyt.util.PageableUtil;
import com.joysuch.wwyt.util.SnowFlakeUtil;
import com.joysuch.wwyt.util.StringUtil;
import com.querydsl.core.types.ExpressionUtils;
import com.querydsl.core.types.Predicate;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;

/**
 * @author: JamesZY
 * @date: 2021/8/24
 * @description:
 */
@Slf4j
@Service
public class ApiV1BpJobServiceImpl implements ApiV1BpJobService {
    @Autowired
    private BpJobDao dao;
    @Autowired
    private RiskDistrictDao riskDistrictDao;
    @Autowired
    private BaseUserDao baseUserDao;
    @Autowired
    private BpJobSyncService jobSyncService;
    @Autowired
    private ApiBpJobMapper jobMapper;
    @Autowired
    private ApiRiskDistrictMapper riskDistrictMapper;
    @Autowired
    private ApiBaseUserMapper userMapper;

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public List<ApiResultData> batchAdd(List<ApiV1BpJobReq> req, BuildDataDto buildDataDto) {
        List<ApiResultData> list = Lists.newArrayList();
        req.forEach(j -> {
            ApiResultData vo = new ApiResultData();
            if (StringUtil.isEmpty(j.getName())) {
                vo.setUniqueId(j.getUniqueId());
                vo.setName(j.getName());
                vo.setMsg("岗位名称不能为空!");
                list.add(vo);
                return;
            }
            if (StringUtil.isEmpty(j.getUniqueId())) {
                vo.setUniqueId(j.getUniqueId());
                vo.setName(j.getName());
                vo.setMsg("岗位唯一编码不能为空!");
                list.add(vo);
                return;
            }
            if (j.getName().length() > 64) {
                vo.setUniqueId(j.getUniqueId());
                vo.setName(j.getName());
                vo.setMsg("岗位名称不能超64字符!");
                list.add(vo);
                return;
            }
            if (j.getUniqueId().length() > 64) {
                vo.setUniqueId(j.getUniqueId());
                vo.setName(j.getName());
                vo.setMsg("岗位唯一编码不能超64字符!");
                list.add(vo);
                return;
            }
            BpJob entity = new BpJob();
            BeanUtils.copyProperties(j, entity);
            //未传第三方唯一标识则通过雪花算法给一个值
            if (StringUtil.isEmpty(j.getUniqueId())) {
                entity.setUniqueId(String.valueOf(SnowFlakeUtil.getJobId()));
            } else {
                ApiBpJobBean jobBean = jobMapper.findByUniqueId(j.getUniqueId(), buildDataDto.getTenentId(), buildDataDto.getOrgCode());
//                BpJob job = dao.findByUniqueId(j.getUniqueId(), 1L, "2");
                if (jobBean != null) {
                    vo.setUniqueId(j.getUniqueId());
                    vo.setName(jobBean.getName());
                    vo.setMsg("唯一编码已存在!");
                    list.add(vo);
                    return;
                }
            }
            if (entity.getStaffCount() == null) {
                entity.setStaffCount(0);
            }
            //名称判重
            int count = jobMapper.countByName(entity.getName(), buildDataDto.getTenentId(), buildDataDto.getOrgCode());
            if (count > 0) {
                vo.setUniqueId(entity.getUniqueId());
                vo.setName(entity.getName());
                vo.setMsg("此名称已存在!");
                list.add(vo);
                return;
            }
            if (entity.getRiskDistrictId() != null) {
                ApiRiskDistrictBean apiRiskDistrictBean = riskDistrictMapper.selectById(entity.getRiskDistrictId());
                if (apiRiskDistrictBean != null) {
                    entity.setRiskDistrictName(apiRiskDistrictBean.getName());
                }
            }
            //调用同步接口
            entity.setOrgCode(buildDataDto.getOrgCode());
            entity.setTenentId(buildDataDto.getTenentId());

            boolean sync = jobSyncService.syncApiJob(entity, buildDataDto);
            if (sync) {
                entity.setLocateSync(true);
            } else {
                entity.setLocateSync(false);
            }
            ApiBpJobBean save = new ApiBpJobBean();
            BeanUtils.copyProperties(entity, save);
            jobMapper.insert(save);
            vo.setUniqueId(save.getUniqueId());
            vo.setName(save.getName());
            list.add(vo);
        });
        return list;
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public void update(ApiV1BpJobUpdateReq data, BuildDataDto buildDataDto) throws ApiV1ExceptionCodeMsg {
        ApiBpJobBean jobBean = jobMapper.findByUniqueId(data.getUniqueId(), buildDataDto.getTenentId(), buildDataDto.getOrgCode());
        if (jobBean == null) {
            throw new ApiV1ExceptionCodeMsg(Status.API_V1_JOB_NOT_EXIST);
        }
        if (StringUtil.notEmpty(data.getName())) {
            if (!data.getName().equals(jobBean.getName())) {
                //名称判重
                int count = jobMapper.countByName(data.getName(), buildDataDto.getTenentId(), buildDataDto.getOrgCode());
                if (count > 0) {
                    throw new ApiV1ExceptionCodeMsg(Status.API_V1_JOB_NAME_EXIST);
                }
                jobBean.setName(data.getName());
            }
        }
        if (StringUtil.notEmpty(data.getDescription())) {
            jobBean.setDescription(data.getDescription());
        }
        BpJob entity = new BpJob();
        BeanUtils.copyProperties(jobBean, entity);
        //调用同步接口
        boolean sync = jobSyncService.syncApiJob(entity, buildDataDto);
        if (sync) {
            jobBean.setLocateSync(true);
        } else {
            jobBean.setLocateSync(false);
        }
        jobBean.setUpdateTime(new Date());
        jobBean.setUpdateBy(-1L);
        jobMapper.updateById(jobBean);
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public List<ApiResultData> deleteByIds(List<String> ids, BuildDataDto buildDataDto) {
        List<ApiResultData> list = Lists.newArrayList();
        ids.forEach(id -> {
            ApiResultData data = new ApiResultData();
            if (StringUtil.notEmpty(id)) {
                ApiBpJobBean jobBean = jobMapper.findByUniqueId(id, buildDataDto.getTenentId(), buildDataDto.getOrgCode());
                if (jobBean == null) {
                    data.setUniqueId(id);
                    data.setMsg("岗位不存在");
                    list.add(data);
                    return;
                }
                List<ApiBaseUserBean> users = userMapper.findByJob(jobBean.getId(), buildDataDto.getTenentId(), buildDataDto.getOrgCode());
                if (!CollectionUtils.isEmpty(users)) {
                    data.setUniqueId(id);
                    data.setMsg("该岗位存在人员，请先移除人员后再删除岗位");
                    list.add(data);
                    return;
                }
                BpJob jobEntity = new BpJob();
                BeanUtils.copyProperties(jobBean, jobEntity);
                //调用同步接口
                boolean sync = jobSyncService.deleteApiSync(jobEntity.getUniqueId(), buildDataDto);
                if (sync) {
                    jobBean.setLocateSync(true);
                } else {
                    jobBean.setLocateSync(false);
                }
                jobBean.setShowState(DataStateTypes.DELETE.getState());
                jobMapper.updateById(jobBean);
                data.setMsg("删除成功");
                data.setUniqueId(jobBean.getUniqueId());
                data.setName(jobBean.getName());
                list.add(data);
            }
        });
        return list;
    }

    @Override
    public ApiPagePropertyDataVo searchAll(ApiV1BpJobQueryReq req, BuildDataDto dto) throws ApiV1ExceptionCodeMsg {
        QueryWrapper<ApiBpJobBean> queryWrapper = new QueryWrapper<>();
        if (ObjectUtil.isNotEmpty(req.getStartUpdateTime())) {
            queryWrapper.ge("UPDATE_TIME", req.getStartUpdateTime());
        }
        if (ObjectUtil.isNotEmpty(req.getEndUpdateTime())) {
            queryWrapper.le("UPDATE_TIME", req.getEndUpdateTime());
        }
        if (StringUtil.notEmpty(req.getName())) {
            queryWrapper.like("NAME", "%" + req.getName() + "%");
        }
        if (StringUtil.notEmpty(req.getUniqueId())) {
            queryWrapper.eq("unique_id", req.getUniqueId());
        }
        queryWrapper.eq("TENENT_ID", dto.getTenentId());
        queryWrapper.eq("ORG_CODE", dto.getOrgCode());
        queryWrapper.eq("DELETE_FLAG", "0");
        queryWrapper.and(QueryWrapper -> QueryWrapper.isNull("show_state").or().eq("show_state", "1"));

        com.baomidou.mybatisplus.extension.plugins.pagination.Page<ApiBpJobBean> page = new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>(req.getPageNumber(), req.getPageSize());
        jobMapper.selectPage(page, queryWrapper);

        List<ApiV1BpJobSearchVo> list = Lists.newArrayList();
        if (CollectionUtils.isEmpty(page.getRecords())) {
            for (ApiBpJobBean bpJob : page.getRecords()) {
                ApiV1BpJobSearchVo vo = new ApiV1BpJobSearchVo();
                bpJob.setStaffCount(baseUserDao.countByJob(bpJob.getId()));
                if (bpJob.getRiskDistrictId() != null) {
                    ApiRiskDistrictBean riskDistrictBean = riskDistrictMapper.selectById(bpJob.getRiskDistrictId());
                    if (riskDistrictBean != null && (riskDistrictBean.getState() == null || riskDistrictBean.getState() != 44)) {
                        bpJob.setRiskDistrictName(riskDistrictBean.getName());
                    }
                }
                vo.setUniqueId(bpJob.getUniqueId());
                vo.setName(bpJob.getName());
                vo.setDescription(bpJob.getDescription());
                vo.setCreateTime(bpJob.getCreateTime());
                vo.setUpdateTime(bpJob.getUpdateTime());
                list.add(vo);
            }
        }
        ApiPagePropertyDataVo apiPagePropertyDataVo = new ApiPagePropertyDataVo();
        apiPagePropertyDataVo.setData(page.getRecords());
        apiPagePropertyDataVo.setTotalElements(page.getTotal());
        apiPagePropertyDataVo.setTotalPages((int) page.getPages());
        apiPagePropertyDataVo.setPresentPage((int) page.getCurrent());
        return apiPagePropertyDataVo;
    }
}
